package com.rabbit.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rabbit.constant.ResultCodeEnum;
import com.rabbit.db.entity.DictData;
import com.rabbit.exception.BusinessException;
import com.rabbit.mapper.DictDataMapper;
import com.rabbit.redis.annotation.Cacheable;
import com.rabbit.redis.constant.RedisKeyConstant;
import com.rabbit.redis.service.RedisService;
import com.rabbit.service.DictDataService;
import com.rabbit.vo.req.DictDataReq;
import com.rabbit.vo.res.DictDataRes;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;

/**
 * <h1>字典键值管理业务实现类</h1>
 *
 * @author zjw
 * @date 2022/02/20 17:32
 */
@Service
public class DictDataServiceImpl implements DictDataService {

    @Resource
    private DictDataMapper dictDataMapper;

    @Override
    public PageInfo<DictDataRes> queryDictDataList(DictDataReq dictDataReq) {
        DictData dictData = DictData.builder().build();
        BeanUtils.copyProperties(dictDataReq, dictData);
        return PageHelper.startPage(dictDataReq.getPage(), dictDataReq.getLimit())
                .doSelectPageInfo(() -> dictDataMapper.queryDictDataList(dictData));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Cacheable(key = RedisKeyConstant.SYS_DICT, cacheType = Cacheable.CACHE_TYPE.UPDATE)
    public void deleteDictData(DictDataReq dictDataReq) {
        dictDataMapper.deleteByPrimaryKey(dictDataReq.getDataId());
    }

    @Override
    @Cacheable(key = RedisKeyConstant.SYS_DICT, cacheType = Cacheable.CACHE_TYPE.UPDATE)
    public void updateDictDataEnabled(DictDataReq dictDataReq) {
        DictData dictData = DictData.builder().dataId(dictDataReq.getDataId()).isEnabled(dictDataReq.getIsEnabled())
                .updateBy(dictDataReq.getOperatorUserName()).build();
        dictDataMapper.updateByPrimaryKeySelective(dictData);
    }

    @Override
    public DictDataRes queryDictDataById(Long dataId) {
        DictData dictData = dictDataMapper.selectByPrimaryKey(dataId);
        DictDataRes dictDataRes = DictDataRes.builder().build();
        BeanUtils.copyProperties(dictData, dictDataRes);
        return dictDataRes;
    }

    @Override
    public void checkUnique(DictDataReq dictDataReq, int operType) throws BusinessException {
        // 1. 字典标签唯一
        Example dictLabelExample = new Example(DictData.class);
        Example.Criteria dictLabelCriteria = dictLabelExample.createCriteria();
        dictLabelCriteria.andEqualTo("dictLabel", dictDataReq.getDictLabel());
        dictLabelCriteria.andEqualTo("dictType", dictDataReq.getDictType());
        if (operType > 1) {
            dictLabelCriteria.andNotEqualTo("dataId", dictDataReq.getDataId());
        }
        if (dictDataMapper.selectCountByExample(dictLabelExample) > 0) {
            throw new BusinessException(ResultCodeEnum.DICT_DATA_LABEL_EXISTS_ERROR);
        }
        // 2. 字典键值唯一
        Example dictValueExample = new Example(DictData.class);
        Example.Criteria dictTypeCriteria = dictValueExample.createCriteria();
        dictTypeCriteria.andEqualTo("dictValue", dictDataReq.getDictValue());
        dictTypeCriteria.andEqualTo("dictType", dictDataReq.getDictType());
        if (operType > 1) {
            dictTypeCriteria.andNotEqualTo("dataId", dictDataReq.getDataId());
        }
        if (dictDataMapper.selectCountByExample(dictValueExample) > 0) {
            throw new BusinessException(ResultCodeEnum.DICT_DATA_VALUE_EXISTS_ERROR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Cacheable(key = RedisKeyConstant.SYS_DICT, cacheType = Cacheable.CACHE_TYPE.UPDATE)
    public void addDictData(DictDataReq dictDataReq) {
        DictData dictData = DictData.builder().build();
        BeanUtils.copyProperties(dictDataReq, dictData);
        dictData.setIsEnabled(true);
        dictData.setCreateBy(dictDataReq.getOperatorUserName());
        dictDataMapper.insertSelective(dictData);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @Cacheable(key = RedisKeyConstant.SYS_DICT, cacheType = Cacheable.CACHE_TYPE.UPDATE)
    public void updateDictData(DictDataReq dictDataReq) {
        DictData dictData = DictData.builder().build();
        BeanUtils.copyProperties(dictDataReq, dictData);
        dictData.setUpdateBy(dictDataReq.getOperatorUserName());
        dictDataMapper.updateByPrimaryKeySelective(dictData);
    }

}
